
#include "UdpServer.h"
#include "../../loop/LoopService.h"
#include "../../common/ErrorCode.h"
#include <event2/util.h>
#include <assert.h>


std::error_code UdpServer::listen(const std::string& ip_port)
{
    struct sockaddr_storage listen_addr = {};
    int socklen = sizeof(listen_addr);

    if (evutil_parse_sockaddr_port(ip_port.c_str(), (struct sockaddr*)&listen_addr, &socklen) < 0){
        return std::make_error_code(std::errc::invalid_argument);
    }

    ez_socket_t fd = ::socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0) {
        return make_socket_error_code(EVUTIL_SOCKET_ERROR());
    }
    if (evutil_make_listen_socket_reuseable(fd) < 0
        || evutil_make_listen_socket_reuseable_port(fd) < 0
        || evutil_make_socket_nonblocking(fd) < 0) {
        evutil_closesocket(fd);
        return make_socket_error_code(EVUTIL_SOCKET_ERROR());
    }

    if (::bind(fd, (struct sockaddr*)&listen_addr, sizeof(listen_addr))) {
        evutil_closesocket(fd);
        return make_socket_error_code(EVUTIL_SOCKET_ERROR());
    }
    local_point_ = listen_addr;
    return attach(fd);
}


